//+------------------------------------------------------------------+
//|                                                      MAStrategy.mq5 |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade/Trade.mqh>

input int      FastMAPeriod = 3;       // 快速均线周期
input int      SlowMAPeriod = 1;       // 慢速均线周期
input double   LotSize      = 0.01;      // 交易手数
input int      StopLoss     = 200;      // 止损点数
input int      TakeProfit   = 400;      // 止盈点数

int handleFastMA, handleSlowMA;
datetime newBarTime;
ENUM_ORDER_TYPE_FILLING  MyFILLING;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   handleFastMA = iMA(_Symbol, PERIOD_CURRENT, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
   handleSlowMA = iMA(_Symbol, PERIOD_CURRENT, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
  
   if(handleFastMA == INVALID_HANDLE || handleSlowMA == INVALID_HANDLE)
     {
      Print("Error creating MA indicators");
      return(INIT_FAILED);
     }

   newBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);

   return(INIT_SUCCEEDED);
  }
//设定该品种Fillingmode  if((filling&SYMBOL_FILLING_FOK)==SYMBOL_FILLING_FOK)
void SetSymbolFillMode(string Symbol_x)
  {
   MyFILLING=ORDER_FILLING_RETURN;
   int FILLING=(int)SymbolInfoInteger(Symbol_x,SYMBOL_FILLING_MODE);
   if((FILLING&SYMBOL_FILLING_IOC)==SYMBOL_FILLING_IOC)
      MyFILLING=ORDER_FILLING_IOC;
   if((FILLING&SYMBOL_FILLING_FOK)==SYMBOL_FILLING_FOK)
      MyFILLING=ORDER_FILLING_FOK;
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   IndicatorRelease(handleFastMA);
   IndicatorRelease(handleSlowMA);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   SetSymbolFillMode(Symbol()); //设定该品种Fillingmode
   static datetime lastBarTime = 0;
   datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);

// 等待新K线
   if(currentBarTime == lastBarTime)
      return;
   lastBarTime = currentBarTime;

// 获取均线数据
   double fastMA[2], slowMA[2];
   if(CopyBuffer(handleFastMA, 0, 0, 2, fastMA) != 2 ||
      CopyBuffer(handleSlowMA, 0, 0, 2, slowMA) != 2)
      return;

// 计算交叉信号
   bool goldenCross = (fastMA[1] < slowMA[1]) && (fastMA[0] > slowMA[0]);
   bool deathCross = (fastMA[1] > slowMA[1]) && (fastMA[0] < slowMA[0]);

// 获取当前持仓
   bool longPosition = PositionSelect(_Symbol);
   bool shortPosition = false;
   if(longPosition)
      shortPosition = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL);

// 计算止损止盈价格
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
   double sl = StopLoss * point;
   double tp = TakeProfit * point;

// 交易逻辑
   if(goldenCross && !longPosition)
     {
      CloseAllPositions();
      MqlTradeRequest request = {};
      MqlTradeResult  result;
      ZeroMemory(request);
      ZeroMemory(result);
      request.action = TRADE_ACTION_DEAL;
      request.symbol = _Symbol;
      request.volume = LotSize;
      request.type = ORDER_TYPE_BUY;
      request.price = ask;
      request.sl = NormalizeDouble(ask - sl,_Digits);
      request.tp = NormalizeDouble(ask + tp,_Digits);
      request.type_filling = MyFILLING;
      OrderSend(request,result);
     }
   else
      if(deathCross && !shortPosition)
        {
         CloseAllPositions();
         MqlTradeRequest request = {};
         MqlTradeResult  result;
         ZeroMemory(request);
         ZeroMemory(result);
         request.action = TRADE_ACTION_DEAL;
         request.symbol = _Symbol;
         request.volume = LotSize;
         request.type = ORDER_TYPE_SELL;
         request.price = bid;
         request.sl = NormalizeDouble( bid + sl,_Digits);
         request.tp = NormalizeDouble( bid - tp,_Digits);
         request.type_filling = MyFILLING;
         OrderSend(request,result);
        }
  }
//+------------------------------------------------------------------+
//| 关闭所有持仓                                                     |
//+------------------------------------------------------------------+
void CloseAllPositions()
  {
   for(int i = PositionsTotal()-1; i >= 0; i--)
     {
      if(PositionGetSymbol(i) == _Symbol)
        {
         MqlTradeRequest request = {};
         MqlTradeResult  result;
         ZeroMemory(request);
         ZeroMemory(result);
         request.action = TRADE_ACTION_DEAL;
         request.symbol = _Symbol;
         request.volume = PositionGetDouble(POSITION_VOLUME);
         request.type = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ?
                        ORDER_TYPE_SELL : ORDER_TYPE_BUY;
         request.price = SymbolInfoDouble(_Symbol, (request.type == ORDER_TYPE_SELL) ?
                                          SYMBOL_BID : SYMBOL_ASK);
         request.type_filling = MyFILLING;
         OrderSend(request,result);
        }
     }
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
